/***
 *  C++ 类
 *  （1）、类的概念
 *  （2）、类的封装:构造函数，析构函数（虚析构函数）， 访问控制（public/privade/protect）
 *  （3）、类的继承:a、按照基础权限（public/privade/protect）
 *                 b、按照继承数量：单继承，多继承（菱形继承：虚继承）
 * 
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>



// 定义“car”类 
class Car { 
    std::string m_brand;    // 数据成员：品牌 
    std::string m_color;    // 颜色
    int m_width;            // 宽
    int m_heigh;            // 高
    double m_speed;         // 速度
public: 
    // 设置默认值
    void init(std::string bStr, std::string sColor, int w, int h, double sp){
        m_brand = bStr;
        m_color = sColor;
        m_width = w;
        m_heigh = h;
        m_speed = sp;
    }
    // 成员函数：设置品牌 
    void setBrand(std::string b) { m_brand = b; } 
    // 成员函数：显示Car信息 
    void showInfo() { 
        std::cout << "Brand:" << m_brand << ", color:" << m_color << " W:" <<  m_width << " H:" << m_heigh  << " speed:" << m_speed << std::endl; 
    } 
}; 

class emptyClass{};

/////////////////////////////////////////////////////////////////////////////////////////////////
// 类的封装
class Book { 
    std::string m_title; 
    int m_pages; 
public: 
    // 构造函数：初始化书籍信息 
    Book(std::string t, int p) { 
        m_title = t;
        m_pages = p;

        std::cout << "构造函数调用："<<" 新书《" << m_title << "》诞生，共" << m_pages << "页" << std::endl; 
    } 
}; 

class ImageLoader { 
    std::string m_imageName; 
public: 
    ImageLoader(std::string nM) { 
        m_imageName = nM;
        std::cout << "构造函数调用，加载图像，分配内存" << std::endl; 
    } 
    ~ImageLoader() {  // 析构函数释放内存 
        std::cout << "析构函数调用图像卸载，内存释放" << std::endl; 
    } 
}; 

class Apartment { 
private:    // 私有权限，默认也是private 
    std::string m_bedroom;  // 卧室（外人不可见） 
protected:  // 保护权限 
    std::string m_study;    // 书房（子类可访问） 
public:     // 公共权限 
    std::string m_livingRoom;  // 客厅（谁都能访问） 
    void cleanRooms() { 
        // 类内可访问所有成员 
        m_bedroom = "整理卧室"; 
        m_study = "打扫书房"; 
        m_livingRoom = "清扫客厅"; 
    } 
    virtual ~Apartment()
    {
        std::cout << "Apartment 析构函数：" << m_bedroom << " " << m_study << " " << m_livingRoom << std::endl;
    }
}; 
class SmallApartment : public Apartment { 
public: 
    ~SmallApartment(){
        std::cout << "SmallApartment 析构函数：" << std::endl;
    }
    void useStudy() { 
        m_study = "在书房工作";  // 子类可访问protected成员 
    } 
}; 
   
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 类的继承
// 基类：交通工具 
class Vehicle { 
public: 
    virtual ~Vehicle(){}
    void move() { 
        std::cout << "Vehicle 移动中... " << m_model << std::endl;
        } 
protected: 
    std::string m_model; 
}; 
    
// public继承：汽车类 
class ChildCar : public Vehicle { 
public: 
    void setModel(std::string m) { 
        m_model = m;  // public继承可访问protected成员 
        move();     // 可访问public成员 
    } 
}; 
    
// protected继承：公交车类 
class Bus : protected Vehicle { 
public: 
    void run() { 
        m_model = "Bus";
        move();  // protected继承，类内可访问 
    } 
}; 
    
// private继承：玩具车类 
class ToyCar : private Vehicle { 
public: 
    void play() { 
        m_model = "ToyCar";
        move();  // private继承，仅类内可用 
    } 
}; 

class Flyable { 
public:
    void func(){
        fly();
    }
private:
    void fly() {
        std::cout << "我可以飞" << std::endl;
    } 
};

class Swimable { 
public:
    void func(){
        swim();
    }
private:
    void swim() {
        std::cout << "我可以游泳" << std::endl;
    } 
};

class FlyingFish : public Flyable, public Swimable {  // 多继承
public:
    void func()
    {
        Flyable::func();
        Swimable::func();
    }
};

// 基类 A
class A {
public:
    ~A(){
        std::cout << "A 析构" << std::endl;
    }
public:
    int value;
};
    
    // B 虚继承 A
class B : virtual public A {
public:
    ~B(){
        std::cout << "B 析构" << std::endl;
    }
};
    
    // C 虚继承 A
class C : virtual public A {
public:
    ~C(){
        std::cout << "C 析构" << std::endl;
    }
};
    
    // D 继承 B 和 C
class D : public B, public C {
public:
    ~D(){
        std::cout << "D 析构" << std::endl;
    }
};

int main(){
    {
        Car c;
        std::cout << "int size:" << sizeof(int) << std::endl;
        std::cout << "double size:" << sizeof(double) << std::endl;
        std::cout << "string size:" << sizeof(std::string) << std::endl;
        std::cout << "class Car size:" << sizeof(Car) << std::endl;
        c.init("奔驰", "red", 2, 4, 120.5);
        c.showInfo();
        
        std::cout << "class emptyClass size:" << sizeof(emptyClass) << std::endl;
    }

    {
        // 类的封装
        Book bk("西游记", 500);
        ImageLoader imgLoader("aaa");

         // 类外只能操作public成员 
         Apartment apt; 
         apt.m_livingRoom = "公共区域"; 
         apt.cleanRooms();

         SmallApartment sApt;
         sApt.cleanRooms();
         sApt.useStudy();
    }

    {
        // 类的继承,继承权限
        Vehicle v;
        v.move();

        ChildCar car;
        car.setModel("ChildCar");

        Bus bus;
        bus.run();

        ToyCar toyCar;
        toyCar.play();

        // 多继承
        FlyingFish f;
        f.func();

        // 菱形继承
        D d;
        d.value = 10;  // 直接访问，无歧义，因虚继承后只有一份 A 的 value
        std::cout << d.value << std::endl;  // 输出 10
    }

    return 0;
}